﻿using BCCommon;
using BCCommon.TMS.Insurance;
using BCData.TMS.Driver;
using BCData.TMS.PersonalInsuranceRecord;
using BCDto.Sim.Admin.Admin;
using BCDto.TMS.PersonalInsuranceRecord;
using BCEntity.Common.EntityNameConst;
using BCEntity.TMS.PersonalInsuranceRecord;
using BCService.Utils;
using System;
using System.Collections.Generic;

namespace BCService.TMS.Insurance.PersonalInsuranceRecord
{
    public class PersonalInsuranceRecordService : IPersonalInsuranceRecordService
    {
        private readonly IPersonalInsuranceRecordData personalInsuranceRecordData;
        private readonly IDriverData driverData;
        private readonly IRedisService redisService;
        private readonly string key = string.Format("{0}", EntityNameConst.PersonalInsuranceRecordEntity);

        public PersonalInsuranceRecordService(IPersonalInsuranceRecordData personalInsuranceRecordData, IRedisService redisService, IDriverData driverData)
        {
            this.personalInsuranceRecordData = personalInsuranceRecordData;
            this.redisService = redisService;
            this.driverData = driverData;
        }

        public PersonalInsuranceRecordDto Add(AdminDto admin, PersonalInsuranceRecordRequestDto dto)
        {
            if (dto.InsuredAmount <= 0)
            {
                throw new ArgumentException("保额不能为空。");
            }
            if (dto.Premium <= 0)
            {
                throw new ArgumentException("保费不能为空。");
            }
            if (dto.ExpirationTime <= dto.EffectiveTime)
            {
                throw new ArgumentException("保险失效日期应该晚于保险生效日期。");
            }
            var entity = dto.As<PersonalInsuranceRecordEntity>();
            entity.CreateTime = DateTime.Now;
            entity.CompanyId = admin.AgentRecord != null ? admin.AgentRecord.CompanyId : admin.CompanyId;
            var driver = this.driverData.GetDriverByIdentityCardNoAsync(dto.IdentityCardNo).GetAwaiter().GetResult();
            if (driver != null)
            {
                entity.DriverId = driver.DriverId;
            }
            var restult = this.personalInsuranceRecordData.InserAsync(entity).GetAwaiter().GetResult();
            if (restult == null)
            {
                throw new ArgumentException("个人保单信息新增失败。");
            }
            return restult.As<PersonalInsuranceRecordDto>();
        }

        public bool Delete(long personalInsuranceRecordId)
        {
            if (!this.personalInsuranceRecordData.ExistsByPersonalInsuranceRecordIdAsync(personalInsuranceRecordId).GetAwaiter().GetResult())
            {
                throw new ArgumentException("个人保单信息不存在。");
            }
            var result = this.personalInsuranceRecordData.DeleteAsync(personalInsuranceRecordId).GetAwaiter().GetResult();
            if (!result)
            {
                throw new ArgumentException("删除个人保单信息失败。");
            }
            string cacheKey = this.redisService.GetKey(key, personalInsuranceRecordId);
            this.redisService.DeleteMultipleKey(cacheKey, false);
            return result;
        }

        public PageableList<PersonalInsuranceRecordDto> GetAll(long? conmpanyId, string underwritingCompany, string insured, string identityCardNo, InsuranceStatus? status, int pageIndex, int pageSize, bool? ascending, string sortName)
        {
            var queryResult = this.personalInsuranceRecordData.GetAllAsync(conmpanyId, underwritingCompany, insured, identityCardNo, status, pageIndex, pageSize, ascending, sortName).GetAwaiter().GetResult();
            return new PageableList<PersonalInsuranceRecordDto>
            {
                Items = queryResult.Item1.As<IEnumerable<PersonalInsuranceRecordDto>>(),
                Count = queryResult.Item2,
                PageIndex = pageIndex,
                PageSize = pageSize
            };
        }

        public PersonalInsuranceRecordDto GetByPersonalInsuranceRecordId(long personalInsuranceRecordId)
        {
            string cacheKey = this.redisService.GetKey(key, personalInsuranceRecordId);
            var result = this.redisService.TryGet(cacheKey, () =>
            {
                var data = this.personalInsuranceRecordData.GetByPersonalInsuranceRecordIdAsync(personalInsuranceRecordId).GetAwaiter().GetResult();

                return data;
            }, TimeSpan.FromDays(30));
            return result.As<PersonalInsuranceRecordDto>();
        }

        public IEnumerable<PersonalInsuranceRecordDto> GetListByIdentityCardNo(string identityCardNo)
        {
            string cacheKey = this.redisService.GetKey(key, identityCardNo);
            var result = this.redisService.TryGet(cacheKey, () =>
            {
                var data = this.personalInsuranceRecordData.GetListByIdentityCardNoAsync(identityCardNo).GetAwaiter().GetResult();
                return data;
            }, TimeSpan.FromDays(30));
            return result.As<IEnumerable<PersonalInsuranceRecordDto>>();
        }

        public PersonalInsuranceRecordDto Update(long personalInsuranceRecordId, PersonalInsuranceRecordRequestDto dto)
        {
            if (!this.personalInsuranceRecordData.ExistsByPersonalInsuranceRecordIdAsync(personalInsuranceRecordId).GetAwaiter().GetResult())
            {
                throw new ArgumentException("个人保单信息不存在。");
            }
            if (dto.InsuredAmount <= 0)
            {
                throw new ArgumentException("保额不能为空。");
            }
            if (dto.Premium <= 0)
            {
                throw new ArgumentException("保费不能为空。");
            }
            if (dto.ExpirationTime <= dto.EffectiveTime)
            {
                throw new ArgumentException("保险失效日期应该晚于保险生效日期。");
            }
            var entity = dto.As<PersonalInsuranceRecordEntity>();
            entity.PersonalInsuranceRecordId = personalInsuranceRecordId;
            var restult = this.personalInsuranceRecordData.UpdateAsync(entity).GetAwaiter().GetResult();
            if (restult == null)
            {
                throw new ArgumentException("个人保单信息修改失败。");
            }
            string cacheKey = this.redisService.GetKey(key, personalInsuranceRecordId);
            this.redisService.DeleteMultipleKey(cacheKey, false);
            return restult.As<PersonalInsuranceRecordDto>();
        }
    }
}
